package com.yuxi.pubInter;


import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.SimplePropertyPreFilter;
import org.dozer.Mapper;
import org.springframework.ui.Model;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.multipart.MultipartFile;
import com.yuxi.common.Const;
import com.yuxi.common.FileUtil;
import com.yuxi.common.ImageUtil;
import com.yuxi.common.StringUtil;
import com.yuxi.common.format.*;
import com.yuxi.pubInter.exception.BusinessException;
import com.yuxi.pubInter.exception.BusinessExceptionEnum;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author sunke
 * @Date 2020-12-11 10:20:59
 * @description
 */

public class BaseController {

    @Resource(name = "skDozerMapper")
    private Mapper mapper;


    @InitBinder
    protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) {

        try {

            DateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            SKCustomDateEditor dateEditor = new SKCustomDateEditor(fmt, true);

            fmt = new SimpleDateFormat("yyyy-MM-dd");
            dateEditor.addDateFormat(fmt);
            fmt = new SimpleDateFormat("yyyy/MM/dd");
            dateEditor.addDateFormat(fmt);

            binder.registerCustomEditor(Date.class, dateEditor);
            binder.registerCustomEditor(int[].class, new IntegerArrayEditor());
            binder.registerCustomEditor(int.class, new IntegerEditor());
            binder.registerCustomEditor(long.class, new LongEditor());
            binder.registerCustomEditor(double.class, new DoubleEditor());
            binder.registerCustomEditor(float.class, new FloatEditor());
            binder.registerCustomEditor(BigDecimal.class, new BigDecimalEditor());


        } catch (Exception e) {


        }

    }


    public <T> List<T> mapList(Collection sourceList, Class<T> destinationClass) {
        if (sourceList == null) {
            return null;
        }


        List<T> destinationList = new ArrayList<T>();


        for (Iterator i$ = sourceList.iterator(); i$.hasNext(); ) {
            Object sourceObject = i$.next();
            Object destinationObject = map(sourceObject, destinationClass);
            destinationList.add((T) destinationObject);
        }
        return destinationList;
    }


    /**
     * 使用dozer技术实现对象的映射.
     *
     * @param source           源对象
     * @param destinationClass 目标对象的类属性
     * @return 目标对象.
     */
    public <T> T map(Object source, Class<T> destinationClass) {
        if (source == null) {
            return null;
        }
        return mapper.map(source, destinationClass);
    }


    /**
     * 使用dozer技术实现把源对象数据给目标对象数据.
     *
     * @param source      源对象
     * @param destination 目标对象
     */
    public void map(Object source, Object destination) {
        mapper.map(source, destination);
    }

    /**
     * 使用dozer技术实现对象的映射.
     *
     * @param source           源对象
     * @param destinationClass 目标对象的类属性
     * @param mapId            需要调用的映射id
     * @return 目标对象.
     */
    public <T> T map(Object source, Class<T> destinationClass, String mapId) {
        if (source == null) {
            return null;
        }
        return mapper.map(source, destinationClass, mapId);
    }

    /**
     * 使用dozer技术实现把源对象数据给目标对象数据.
     *
     * @param source      源对象
     * @param destination 目标对象
     * @param mapId       需要调用的映射id
     */
    public void map(Object source, Object destination, String mapId) {
        if (source == null) {
            return;
        }
        mapper.map(source, destination, mapId);
    }


    /**
     * 上传文件
     *
     * @param file      文件
     * @param frontPath 上传的目录
     * @param fileName
     * @param suffixs   允许的后缀
     * @return
     * @throws BusinessException
     */
    public String uploadFile(MultipartFile file, String frontPath, String fileName, String[] suffixs) throws BusinessException {


        if (file == null) {
            throw new BusinessException(BusinessExceptionEnum.FILE_NULL_ERROR);
        }
        if (file.getSize() == 0) {
            throw new BusinessException(BusinessExceptionEnum.FILE_NULL_ERROR);
        }
        String[] fileSplit = null;
        fileSplit = file.getOriginalFilename().split("\\.");
        String suffix = fileSplit[fileSplit.length - 1];

        if (suffixs != null && suffix.length() > 0) {
            boolean isValid = false;
            for (int i = 0; i < suffixs.length; i++) {
                if (suffixs[i].equalsIgnoreCase(suffix)) {
                    isValid = true;
                    break;
                }
            }
            if (!isValid) {
                throw new BusinessException(BusinessExceptionEnum.FILE_FORMAT_ERROR);
            }
        }

        //   fileName = fileName;
        String dir = Const.UPLOAD_PATH + File.separator + frontPath;
        FileUtil.mkdirs(dir);

        if (!fileName.contains("\\.")) {
            fileName = fileName + "." + suffix;
        }

        File targetFile = new File(dir, fileName);

        try {
            file.transferTo(targetFile); // 保存
        } catch (Exception e) {
            throw new BusinessException(e.getMessage());
        }
        return StringUtil.swayStr(frontPath + File.separator + fileName);


    }


    /**
     * 只保留要的字段
     *
     * @param src
     * @param clazz
     * @param args
     * @param <T>
     * @return
     */
    public <T> T filterIncludesFieldsJson(Object src, Class<T> clazz, String... args) {

        return filterFieldsJson(src, clazz, true, args);
    }

    /**
     * 排除不要的字段
     *
     * @param src
     * @param clazz
     * @param args
     * @param <T>
     * @return
     */
    public <T> T filterExcludesFieldsJson(Object src, Class<T> clazz, String... args) {
        return filterFieldsJson(src, clazz, false, args);
    }

    public Map filterExcludesFieldsJson(Object src, String... args) {
        return filterFieldsJson(src, Map.class, false, args);
    }

    public Map filterFieldsJson(Object src, boolean includes, String... args) {
        return filterFieldsJson(src, Map.class, includes, args);
    }


    //过滤方法  字段为空也输出 增加一个参数 SerializerFeature.WriteMapNullValue
    public <T> T filterFieldsJson(Object src, Class<T> clazz, boolean includes, String... args) {
        SimplePropertyPreFilter filter = new SimplePropertyPreFilter();
        if (StringUtil.isNotObjEmpty(args)) {
            for (String pro : args) {
                if (includes) {
                    filter.getIncludes().add(pro);
                } else {
                    filter.getExcludes().add(pro);
                }
            }
        }

        return JSONObject.parseObject(JSONObject.toJSONString(src, filter, SerializerFeature.WriteMapNullValue), clazz);
    }


    public String getUploadFile(MultipartFile file, String frontStr, String[] suffixs, float scale, float outputQualitySize) throws BusinessException {

        String fileName = "";
        if (file == null) {
            throw new BusinessException(BusinessExceptionEnum.FILE_NULL_ERROR);
        }
        if (file.getSize() == 0) {
            throw new BusinessException(BusinessExceptionEnum.FILE_NULL_ERROR);
        }

        String[] fileSplit = null;
        String path = Const.UPLOAD_PATH + File.separator + frontStr;

        fileSplit = file.getOriginalFilename().split("\\.");

        if (fileSplit == null || fileSplit.length < 2) {
            throw new BusinessException(BusinessExceptionEnum.FILE_FORMAT_ERROR);
        }

        String suffix = fileSplit[fileSplit.length - 1];

        if (suffixs != null && suffix.length() > 0) {
            boolean isValid = false;
            for (int i = 0; i < suffixs.length; i++) {
                if (suffixs[i].equalsIgnoreCase(suffix)) {
                    isValid = true;
                    break;
                }
            }
            if (!isValid) {
                throw new BusinessException(BusinessExceptionEnum.FILE_FORMAT_ERROR);
            }
        }


        fileName = StringUtil.createOrderNo(20) + "." + suffix;
        FileUtil.mkdirs(path);
        File targetFile = new File(path, fileName);

        try {

            file.transferTo(targetFile); // 保存

            if (scale != 1 || outputQualitySize != 1) {

                ImageUtil.outputQuality(path + File.separator + fileName, scale, outputQualitySize);

            }


        } catch (Exception e) {
            throw new BusinessException(e.getMessage());
        }
        return StringUtil.swayStr(frontStr + File.separator + fileName);


    }


    public String getUploadFile(MultipartFile file, String frontStr, String[] suffixs) throws BusinessException {


        return getUploadFile(file, frontStr, suffixs, 1, 1);

    }

    public void getUploadPath(Model model) {
        model.addAttribute("imgPath", Const.UPLOAD_PATH);
    }


}
